﻿using ctolua.Models.Class;
using ctolua.Models.Enum;
using ctolua.Models.Expand;
using ctolua.Models.System;
using ctolua.Models.Type;
using ctolua.sys;
using System.Data;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace ctolua.Models.UI
{

    /// <summary>
    /// UI
    /// </summary>
    public class Mui
    {
        /// <summary>
        /// uid
        /// </summary>
        public string id { get; set; }
        /// <summary>
        /// 玩家
        /// </summary>
        public Role role = MRole.getOwnerRole.role;
        /// <summary>
        /// 父ui名字
        /// </summary>
        public string parent { get; set; }

        private EUi _type { get; set; }
        /// <summary>
        /// ui类型
        /// </summary>
        public virtual EUi type { get => _type; set => _type = value; }


        public double? _x  = 960;
        /// <summary>
        /// x
        /// </summary>
        public double? x
        {
            get => this._x;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_pos(this.role, this.id, value, this.y);
                }
                _x = value;
            }
        }


        public double? _y { get; set; } = 540;
        /// <summary>
        /// y
        /// </summary>
        public double? y
        {
            get => this._y;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_pos(this.role, this.id, this.x, value);
                }
                _y = value;

            }
        }
        private bool? _show { get; set; } = true;
        /// <summary>
        /// 显示/隐藏
        /// </summary>
        public bool? show
        {
            get => this._show;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_visible(this.role, value, this.id);
                }
                _show = value;
            }
        }
        private double? _opacity { get; set; }
        /// <summary>
        /// 透明度 1-100
        /// </summary>
        public double? opacity
        {
            get => this._opacity;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_opacity(this.role, this.id, value);
                }
                _opacity = value;
            }
        }

        private int? _z_order { get; set; }
        /// <summary>
        /// 深度
        /// </summary>
        public int? z_order
        {
            get => this._z_order;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_z_order(this.role, this.id, value);
                }

                _z_order = value;
            }
        }

        private bool? _isdrag { get; set; }
        /// <summary>
        /// 是否可拖动
        /// </summary>
        public bool? isdrag
        {
            get => this._isdrag;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_drag(this.role, this.id, value);
                }

                _isdrag = value;
            }

        }
        private size _scale { get; set; }
        /// <summary>
        /// 缩放
        /// </summary>
        public size scale
        {
            get => this._scale;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_scale(this.role, this.id, value.Width, value.Height);
                }

                _scale = value;
            }

        }

        private bool? _intercepts { get; set; }
        /// <summary>
        /// 是否拦截操作
        /// </summary>
        public bool? intercepts
        {
            get => this._intercepts;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_swallow(this.role, this.id, value);
                }

                _intercepts = value;
            }

        }

        private double? _rot { get; set; }
        /// <summary>
        /// 设置控件相对旋转
        /// </summary>
        public double? rot
        {
            get => this._rot;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_rotation(this.role, this.id, value);
                }

                _rot = value;
            }

        }

        private vec3 _absolute_pos { get; set; }
        /// <summary>
        /// 设置绝对坐标
        /// </summary>
        public vec3 absolute_pos
        {
            get => this._absolute_pos;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_world_pos(this.role, this.id, value.x, value.y);
                }

                _absolute_pos = value;
            }

        }

        private double? _absolute_rot { get; set; }
        /// <summary>
        /// 设置控件绝对旋转
        /// </summary>
        public double? absolute_rot
        {
            get => this._absolute_rot;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_world_rotation(this.role, this.id, value);
                }

                _absolute_rot = value;
            }

        }

        private vec3 _absolute_scale { get; set; }
        /// <summary>
        /// 设置控件绝对缩放
        /// </summary>
        public vec3 absolute_scale
        {
            get => this._absolute_scale;
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_world_scale(this.role, this.id, value.x, value.y);
                }

                _absolute_scale = value;
            }

        }

        private double? _h { get; set; }
        /// <summary>
        /// 高
        /// </summary>
        public double? h
        {
            get
            {
                if (this._h == null)
                {
                    return this.get_height();
                }
                else
                {
                    return this._h;
                }

            }
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_size(this.role, this.id, this.w, value);
                }

                _h = value;
            }

        }

        private double? _w { get; set; }
        /// <summary>
        /// 宽
        /// </summary>
        public double? w
        {
            get
            {
                if (this._w == null)
                {
                    return this.get_width();
                }
                else
                {
                    return this._w;
                }

            }
            set
            {
                if (value != null)
                {
                    game_api.set_ui_comp_size(this.role, this.id, value, this.h);
                }

                _w = value;
            }

        }

        private bool? _follow_mouse { get; set; }
        /// <summary>
        /// 控件跟随鼠标
        /// </summary>
        public bool? follow_mouse
        {
            get => this._follow_mouse;
            set
            {
                if (value != null)
                {
                    this.set_ui_comp_follow_mouse(value,null,null);
                }
                _follow_mouse = value;
            }

        }

        

        public Mui() { }
        /// <summary>
        /// uid转对象
        /// </summary>
        /// <param name="id"></param>
        public Mui(string id)
        {

            this.id = id;
        }

        public Mui(Mui u)
        {
            try
            {
                this.role = u.role;
                this.parent = u.parent;
                this.type = u.type;

                create();
                this.x = u.x;
                this.y = u.y;
                this.w = u.w;
                this.h = u.h;
                this.scale = u.scale;
            }
            catch
            {
                if (string.IsNullOrEmpty(this.parent))
                {
                    Console.WriteLine("创建 UI parent 不为空");
                }
            }
            
            
        }
        /// <summary>
        /// 创建ui
        /// </summary>
        public void create()
        {
            string uid = get_absolute_path(this.parent);
            if (uid==null)
            {
                uid = this.parent;
            }
            id = game_api.create_ui_comp(this.role, uid, (int)this.type);
        }

        

        /// <summary>
        /// 通过绝对路径获得ui控件
        /// </summary>
        /// <param name="parent"></param>
        /// <returns></returns>
        public string get_absolute_path(string parent)
        {
            string uid = game_api.get_comp_by_absolute_path(this.role, parent);
            if (uid == null)
            {
                uid = this.parent;
            }
            return uid;
        }

        /// <summary>
        /// 通过绝对路径获得ui控件
        /// </summary>
        /// <param name="role ">  玩家   </param>
        /// <param name="path ">  路径   </param>
        /// <returns>控件uid</returns>
        public static string get_absolute_path(Role role, string path)
        {
            string uid = game_api.get_comp_by_absolute_path(role, path);
            if (uid == null)
            {
                uid = path;
            }
            return uid;
        }


        /// <summary>
        /// 获取ui控件的名称
        /// </summary>
        /// <returns></returns>
        public string get_name()
        {
            return game_api.get_ui_comp_name(this.role, this.id);
        }

        /// <summary>
        /// 创建并绑定ui控件事件
        /// </summary>
        /// <param name="event_type">控件事件类型</param>
        /// <returns></returns>
        public string events(EEventType event_type)
        {
            return game_api.create_ui_comp_event(this.role, this.id, (int)event_type);
        }



        /// <summary>
        /// 新版创建并绑定ui控件事件(指定事件名),不再传入玩家，同时支持普通控件和动态创建控件
        /// </summary>
        /// <param name = "event_type" > 控件事件类型 </ param >
        /// < param name="event_name">自定义事件名</param>
        /// <param name = "fun" > 执行事件 </ param >
        /// < returns > 事件名 </ returns >
        public string event_ex_ex<T>(EEventType event_type, string event_name, Action<string, T, MRole> fun) where T : Mui, new()
        {

            string str = game_api.create_ui_comp_event_ex_ex(this.id, (int)event_type, event_name);
            //        --"data" = {'__ui_event_name': 'a9ae28a3-5acb-55a5-d2ea-1f6ce9ea31e6', '__comp_name': '482a5bb1-a60c-4a3a-8c7b-673b801b15ef', '__role_id': 1}
            return GT.add_event(TGlobalEventType.UI_EVENT, event_name, (_, data) =>
            {
                T t = new T();
                t.id = data.data.__comp_name;
                fun(data.data.__ui_event_name, t, MRole.get_role_by_id(data.data.__role_id));
            });
        }
        /// <summary>
        /// 进入事件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="fun">回调函数</param>
        public void 进入<T>(Action<string, T, MRole> fun) where T : Mui, new()
        {
            this.event_ex_ex<T>(EEventType.进入, SUuid.uuid(), fun);

        }

        /// <summary>
        /// 离开事件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="fun">回调函数</param>
        public void 离开<T>(Action<string, T, MRole> fun) where T : Mui, new()
        {
            this.event_ex_ex<T>(EEventType.离开, SUuid.uuid().ToString(), fun);
        }

        /// <summary>
        /// 双击事件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="fun">回调函数</param>
        public void 双击<T>(Action<string, T, MRole> fun) where T : Mui, new()
        {
            this.event_ex_ex<T>(EEventType.双击, SUuid.uuid().ToString(), fun);
        }

        /// <summary>
        /// 右击事件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="fun">回调函数</param>
        public void 右击<T>(Action<string, T, MRole> fun) where T : Mui, new()
        {
            this.event_ex_ex<T>(EEventType.右击, SUuid.uuid().ToString(), fun);
        }

        /// <summary>
        /// 悬停事件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="fun">回调函数</param>
        public void 悬停<T>(Action<string, T, MRole> fun) where T : Mui, new()
        {
            this.event_ex_ex<T>(EEventType.悬停, SUuid.uuid().ToString(), fun);
        }

        /// <summary>
        /// 点击事件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="fun">回调函数</param>
        public void 点击<T>(Action<string, T, MRole> fun) where T : Mui, new()
        {
            this.event_ex_ex<T>(EEventType.点击, SUuid.uuid().ToString(), fun);
        }

        /// <summary>
        /// 长按事件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="fun">回调函数</param>
        public void 长按<T>(Action<string, T, MRole> fun) where T : Mui, new()
        {
            this.event_ex_ex<T>(EEventType.长按, SUuid.uuid().ToString(), fun);
        }


        /// <summary>
        /// 通过控件+路径获得ui控件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <returns>T</returns>
        public T get_comp_by_path<T>(string path) where T : Mui, new()
        {
            T t = new T();
            t.id = game_api.get_comp_by_path(this.role, this.id, path);
            return t;
        }

        /// <summary>
        /// 通过控件+路径获得ui控件
        /// </summary>
        /// <param name="role ">  玩家   </param>
        /// <param name="comp_name ">  父节点   </param>
        /// <param name="path ">  路径   </param>
        /// <returns>T</returns>
        public static T get_comp_by_path<T>(Role role, string comp_name, string path) where T : Mui, new()
        {
            T t = new T();
            t.id = game_api.get_comp_by_path(role, comp_name, path);
            return t;
        }

        /// <summary>
        /// 通过控件+路径获得ui控件
        /// </summary>
        /// <param name="role ">  玩家   </param>
        /// <param name="comp_name ">  父节点   </param>
        /// <param name="path ">  路径   </param>
        /// <returns>控件uid</returns>
        public static string get_comp_by_path_id(Role role, string comp_name, string path)
        {
            return game_api.get_comp_by_path(role, comp_name, path);
        }

        /// <summary>
        /// 界面组件转字符串
        /// </summary>
        /// <returns></returns>
        public string ui_comp_to_str() => game_api.ui_comp_to_str(this.id);


        /// <summary>
        /// 界面组件是否存在
        /// </summary>
        /// <returns></returns>
        public bool? is_null => game_api.ui_comp_is_exist(this.id);


        /// <summary>
        /// 获得界面控件的父控件
        /// </summary>
        /// <returns></returns>
        public string get_ui_comp_parent() => game_api.get_ui_comp_parent(this.role, this.id);


        /// <summary>
        /// 获取本地控件相对旋转
        /// </summary>
        /// <returns></returns>
        public double? get_ui_comp_rotation() => game_api.get_ui_comp_rotation(this.id).@float();


        /// <summary>
        /// 获取本地控件绝对旋转
        /// </summary>
        /// <returns></returns>
        public double? get_ui_comp_world_rotation() => game_api.get_ui_comp_world_rotation(this.id).@float();


        /// <summary>
        /// 删除界面控件
        /// </summary>
        /// <returns></returns>
        public void del()
        {
            game_api.del_ui_comp(this.role, this.id);
        }

        /// <summary>
        /// 获得控件宽度
        /// </summary>
        /// <returns></returns>
        public int? get_width() => game_api.get_ui_comp_width(this.id);


        /// <summary>
        /// 获得控件高度
        /// </summary>
        /// <returns></returns>
        public int? get_height() => game_api.get_ui_comp_height(this.id);


        /// <summary>
        /// 设置界面组件的对齐方式
        /// </summary>
        /// <param name="type">对齐方式</param>
        public void set_ui_comp_align(int type)
        {
            game_api.set_ui_comp_align(this.role, this.id, type);
        }

        /// <summary>
        /// 隐藏ui组件并播放动画
        /// </summary>
        /// <param name="anim_name">动画名</param>
        public void hide_ui_comp_animation(string anim_name)
        {
            game_api.hide_ui_comp_animation(this.role, this.id, anim_name);
        }
        /// <summary>
        /// 获得玩家控件显隐性
        /// </summary>
        /// <returns>是否显示</returns>
        public bool? visible()
        {
            return game_api.get_ui_comp_visible(this.role, this.id);
        }

        /// <summary>
        /// 解绑绑定控件
        /// </summary>
        public void unbind_ui_comp()
        {
            game_api.unbind_ui_comp(this.role, this.id);
        }
        /// <summary>
        /// 设置ui开启/关闭
        /// </summary>
        /// <param name="current_value">是否开启</param>
        public void set_ui_comp_enable(bool? current_value)
        {
            game_api.set_ui_comp_enable(this.role, this.id, current_value);
        }

        /// <summary>
        /// 设置预设主界面UI显隐
        /// </summary>
        /// <param name="visible">显隐</param>
        public void set_prefab_ui_show(bool? visible)
        {
            game_api.set_prefab_ui_visible(this.role, visible);
        }

        /// <summary>
        /// 遍历某个界面控件的子节点
        /// </summary>
        /// <returns></returns>
        public List<string> get_ui_comp_children()
        {
            List<string> lua_table = new List<string>();
            string py_list = game_api.get_ui_comp_children(this.role, this.id);
            Console.WriteLine();
            Console.WriteLine(py.json(this.role));
            Console.WriteLine(this.id);
            Console.WriteLine(py.python_len(py_list));
            for (int i = 1; i < py.python_len(py_list) - 1; i++)
            {
                lua_table.Add(py.python_index(py_list, i));
            }
            return lua_table;
        }
        /// <summary>
        /// 获取本地控件相对坐标的X
        /// </summary>
        /// <returns></returns>
        public double? get_ui_comp_pos_x()
        {
            return game_api.get_ui_comp_pos_x(this.id).@float();
        }
        /// <summary>
        /// 获取当前玩家控件相对位置y
        /// </summary>
        /// <param name="comp_name ">  控件名   </param>
        /// <returns>y</returns>
        public double? get_ui_comp_pos_y()
        {

            return game_api.get_ui_comp_pos_y(this.id).@float();
        }

        /// <summary>
        /// 获取当前玩家控件绝对位置x
        /// </summary>
        /// <returns>x</returns>
        public double? get_ui_comp_world_pos_x()
        {
            return game_api.get_ui_comp_world_pos_x(this.id).@float();
        }

        /// <summary>
        /// 获取当前玩家控件绝对位置y
        /// </summary>
        /// <returns>y</returns>
        public double? get_ui_comp_world_pos_y()
        {
            return game_api.get_ui_comp_world_pos_y(this.id).@float();
        }

        /// <summary>
        /// 获取当前玩家控件相对缩放x
        /// </summary>
        /// <returns>scale_x</returns>
        public double? get_ui_comp_scale_x()
        {
            return game_api.get_ui_comp_scale_x(this.id).@float();
        }

        /// <summary>
        /// 获取当前玩家控件相对缩放y
        /// </summary>
        /// <returns>scale_y</returns>
        public double? get_ui_comp_scale_y()
        {
            return game_api.get_ui_comp_scale_y(this.id).@float();
        }

        /// <summary>
        /// 获取当前玩家控件绝对缩放x
        /// </summary>
        /// <returns>scale_x</returns>
        public double? get_ui_comp_world_scale_x()
        {
            return game_api.get_ui_comp_world_scale_x(this.id).@float();
        }

        /// <summary>
        /// 获取当前玩家控件绝对缩放y
        /// </summary>
        /// <returns>scale_y</returns>
        public double? get_ui_comp_world_scale_y()
        {
            return game_api.get_ui_comp_world_scale_y(this.id).@float();
        }

        /// <summary>
        /// 获得界面控件所属的界面模块实例(如果是的话)
        /// </summary>
        /// <returns></returns>
        public string get_ui_comp_prefab()
        {
            return game_api.get_ui_comp_prefab(this.role, this.id);
        }
        /// <summary>
        /// 生成漂浮文字
        /// </summary>
        /// <param name="point"> 点 </param>
        /// <param name="text_type"> 跳字枚举 </param>
        /// <param name="value"> 跳字内容 </param>
        /// <param name="player_group"> 玩家组 </param>
        /// Mui.create_harm_text(u.pos.point, (int)EFloating.系统文字, "6666", MRoleGroup.get_all_role_ids.roleGroup);
        /// <returns></returns>
        public static void create_harm_text(Point point, int text_type, string value, RoleGroup player_group)
        {
            game_api.create_harm_text(point,  text_type,  value,  player_group);
        }

        /// <summary>
        /// 播放ui动效
        /// </summary>
        /// <param name="fx_id ">  控件动效工程id   </param>
        /// <param name="ani_name ">  动效名   </param>
        /// <returns></returns>
        public void play_ui_comp_fx(string uid, int? fx_id, string ani_name, bool? loop)
        {
            game_api.play_ui_comp_fx(this.role, uid, fx_id, ani_name, loop);
        }
        /// <summary>
        /// 界面控件属性动态绑定主控单位
        /// </summary>
        public void ui_comp_bind_ctrl_unit()
        {
            game_api.ui_comp_bind_ctrl_unit(this.role, this.id);
        }
        /// <summary>
        /// 设置界面适配
        /// </summary>
        /// <param name="direction"></param>
        /// <param name="value"></param>
        public Mui adaptation(EUiAdaptOption direction, double? value)
        {
            game_api.set_ui_comp_adapt_option(this.role, this.id, (int)direction, value);
            return this;
        }
        /// <summary>
        /// 控件适配0
        /// </summary>
        public void relative0()
        {
            this.adaptation(EUiAdaptOption.顶部, 0)
                .adaptation(EUiAdaptOption.底部, 0)
                .adaptation(EUiAdaptOption.右侧, 0)
                .adaptation(EUiAdaptOption.左侧, 0);
        }
        /// <summary>
        /// 控制控件跟随鼠标
        /// </summary>
        /// <param name="role"> 玩家 </param>
        /// <param name="comp_name"> 控件uid </param>
        /// <param name="is_follow"> 是否跟随 </param>
        /// <param name="offset_x"> 偏移x </param>
        /// <param name="offset_y"> 偏移y </param>
        /// <returns></returns>
        public void set_ui_comp_follow_mouse(bool? is_follow, double? offset_x, double? offset_y)
        {
            game_api.set_ui_comp_follow_mouse(this.role, this.id,   is_follow, offset_x,  offset_y);
        }

        /// <summary>
        /// 根据指定玩家操作UI
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="role"></param>
        /// <returns></returns>
        public T r<T>(Role role) where T : Mui, new()
        {
            dynamic obj = SCache.getUICache<T>( role,this.id);
            
            if (obj==null)
            {
                T t = new T();
                t.id = this.id;
                t.role = role;
                obj = t;
                SCache.setUICache(role, this.id,obj);
            }
            return obj;
        }
        /// <summary>
        /// 根据指定玩家ID操作UI
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public T r<T>(int id) where T : Mui, new()
        {
            Role role = MRole.get_role_by_id(id).role;
            return r<T>(role);
        }
        /// <summary>
        /// 根据指定玩家对象操作UI
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="r"></param>
        /// <returns></returns>
        public T r<T>(MRole role) where T : Mui, new()
        {
            return r<T>(role.role);
        }

        public override string? ToString()
        {
            return py.toString(this.id);
        }
    }
}
